package it.canraid.texthere;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.location.Location;
import android.os.Handler;

import de.mindpipe.android.logging.log4j.LogConfigurator;

public class Cfunctions {
	public static final String type_operation ="type_operation";
	public static final String id_track_commit ="id track commit";
	public static final String MTX_EMAIL="MTX_EMAIL";
	public static final String STX_USERID_CASE_SENSITIVE="STX_USERID_CASE_SENSITIVE";
	public static final String STX_MD5_PASSWORD="STX_MD5_PASSWORD";
	public static final String PK_SESSION="PK_SESSION";
	public static final String INT_KEY_REGISTER ="INT_KEY_REGISTER";
	public static final String LNG_LAST_MACRO_BOUND_REFRESH="LNG_LAST_MACRO_BOUND_REFRESH";
	public static final String left_bound_latitude ="left_bound_latitude";
	public static final String right_bound_latitude ="right_bound_latitude";
	public static final String top_bound_latitude ="top_bound_latitude";
	public static final String bottom_bound_latitude="bottom_bound_latitude";
	public static final String PK_COMMENT="PK_COMMENT";
	public static final String PK_MESSAGE="PK_MESSAGE";
	public static final String FK_MESSAGE="FK_MESSAGE";
	public static final String TMS_CREATED="TMS_CREATED";
	public static final String QTY_LIKE="QTY_LIKE";
	public static final String QTY_UNLIKE="QTY_UNLIKE";
	public static final String i_liked_unliked_this="i_liked_unliked_this";
	public static final String add_less_like_unlike="add_less_like_unlike";
	public static final String LTX_COMMENT="LTX_COMMENT";
	public static final String TMS_LAST_MESSAGE_UPDATE="TMS_LAST_MESSAGE_UPDATE";
	public static final String TMS_LAST_COMMENT_UPDATE="TMS_LAST_COMMENT_UPDATE";
	public static final String LNG_LATITUDE_IDX="LNG_LATITUDE_IDX";
	public static final String LNG_LONGITUDE_IDX="LNG_LONGITUDE_IDX";
	public static final String ms_up_to_expiration="ms_up_to_expiration";
	public static final String LTX_MESSAGE="LTX_MESSAGE";
	public static final String FLC_LIKE_UNLIKE="FLC_LIKE_UNLIKE";
	public static final String error="error";
	public static final String outcome_response="outcome response";
	public static final String messages="messages";
	public static final String comments="comments";
	public static final String type_operation_ping="ping";
	public static final String type_operation_registration="registration";
	public static final String type_operation_login="login";
	public static final String type_operation_logout="logout";
	public static final String type_operation_code_registration="code registration";
	public static final String type_operation_refresh="refresh";
	public static final String type_operation_commit_message="commit message";
	public static final String type_operation_commit_comment="commit comment";
	public static final String type_operation_commit_preference="commit preference";
	public static final String where_preference ="where";
	private static SimpleDateFormat simpleDateTimeFormat = new SimpleDateFormat("dd/MM/yyyy' 'kk:mm:ss:S");
	
	private FntwAgent ntwAgent=null;
	

	public synchronized String ping(){
		JSONObject jsonReq=new JSONObject();
		jsonReq.put(Cfunctions.type_operation, Cfunctions.type_operation_ping);
		ntwAgent=new FntwAgent(jsonReq.toString(), null);
		
		return ntwAgent.sendAndWaitResponse();
	}
	
	public synchronized String sendRegistrationSync(String MTX_EMAIL, String STX_USERID_CASE_SENSITIVE, 
			String STX_MD5_PASSWORD){
		JSONObject jsonReq=new JSONObject();
		jsonReq.put(Cfunctions.type_operation, Cfunctions.type_operation_registration);
		jsonReq.put(Cfunctions.MTX_EMAIL, MTX_EMAIL);
		jsonReq.put(Cfunctions.STX_MD5_PASSWORD, STX_MD5_PASSWORD);
		jsonReq.put(Cfunctions.STX_USERID_CASE_SENSITIVE, STX_USERID_CASE_SENSITIVE);
		ntwAgent=new FntwAgent(jsonReq.toString(), null);
		
		return ntwAgent.sendAndWaitResponse();
	}
	
	public synchronized String sendLoginSync(String MTX_EMAIL,  String STX_MD5_PASSWORD){
		JSONObject jsonReq=new JSONObject();
		jsonReq.put(Cfunctions.type_operation, Cfunctions.type_operation_login);
		jsonReq.put(Cfunctions.MTX_EMAIL, MTX_EMAIL);
		jsonReq.put(Cfunctions.STX_MD5_PASSWORD, STX_MD5_PASSWORD);
		ntwAgent=new FntwAgent(jsonReq.toString(), null);
		
		return ntwAgent.sendAndWaitResponse();
	}
	
	public synchronized String sendLogoutSync(int PK_SESSION){
		JSONObject jsonReq=new JSONObject();
		jsonReq.put(Cfunctions.type_operation, Cfunctions.type_operation_logout);
		jsonReq.put(Cfunctions.PK_SESSION, PK_SESSION);
		ntwAgent=new FntwAgent(jsonReq.toString(), null);
		
		return ntwAgent.sendAndWaitResponse();
	}
	
	public synchronized String sendCodeRegistrationSync(String MTX_EMAIL,  String STX_MD5_PASSWORD, int INT_KEY_REGISTER){
		JSONObject jsonReq=new JSONObject();
		jsonReq.put(Cfunctions.type_operation, Cfunctions.type_operation_code_registration);
		jsonReq.put(Cfunctions.INT_KEY_REGISTER, INT_KEY_REGISTER);
		jsonReq.put(Cfunctions.MTX_EMAIL, MTX_EMAIL);
		jsonReq.put(Cfunctions.STX_MD5_PASSWORD, STX_MD5_PASSWORD);
		ntwAgent=new FntwAgent(jsonReq.toString(), null);
		
		return ntwAgent.sendAndWaitResponse();
	}
	
	public void sendRefresh(int PK_SESSION, long LNG_LAST_MACRO_BOUND_REFRESH, long left_bound_latitude, 
			long right_bound_latitude, long top_bound_latitude, long bottom_bound_latitude, Handler handlerTo){
		JSONObject jsonReq=new JSONObject();
		jsonReq.put(Cfunctions.type_operation, Cfunctions.type_operation_refresh);
		jsonReq.put(Cfunctions.PK_SESSION, PK_SESSION);
		jsonReq.put(Cfunctions.LNG_LAST_MACRO_BOUND_REFRESH, LNG_LAST_MACRO_BOUND_REFRESH);
		jsonReq.put(Cfunctions.left_bound_latitude, left_bound_latitude);
		jsonReq.put(Cfunctions.right_bound_latitude, right_bound_latitude);
		jsonReq.put(Cfunctions.top_bound_latitude, top_bound_latitude);
		jsonReq.put(Cfunctions.bottom_bound_latitude, bottom_bound_latitude);
		
		ntwAgent=new FntwAgent(jsonReq.toString(), handlerTo);
		ntwAgent.start();
	}
	
	public void sendCommit(int PK_SESSION, Object object, Handler handlerTo, String id_track_commit){
		JSONObject jsonReq=new JSONObject();
		jsonReq.put(Cfunctions.PK_SESSION, PK_SESSION);
		jsonReq.put(Cfunctions.id_track_commit, id_track_commit);
		boolean foundIt=false;
		if (object instanceof Emessage){
			Emessage message=(Emessage)object;
			foundIt=true;
			jsonReq.put(Cfunctions.type_operation, Cfunctions.type_operation_commit_message);
			jsonReq.put(Cfunctions.LNG_LATITUDE_IDX, message.LNG_LATITUDE_IDX);
			jsonReq.put(Cfunctions.LNG_LONGITUDE_IDX, message.LNG_LONGITUDE_IDX);
			jsonReq.put(Cfunctions.ms_up_to_expiration, message.ms_up_to_expiration);
			jsonReq.put(Cfunctions.LTX_MESSAGE, message.LTX_MESSAGE);
		}
		else if (object instanceof Ecomment){
			Ecomment comment=(Ecomment)object;
			foundIt=true;
			jsonReq.put(Cfunctions.type_operation, Cfunctions.type_operation_commit_comment);
			jsonReq.put(Cfunctions.FK_MESSAGE, comment.FK_MESSAGE);
			jsonReq.put(Cfunctions.LTX_COMMENT, comment.LTX_COMMENT);	
		}
		else if (object instanceof Epreference){
			Epreference preference=(Epreference)object;
			jsonReq.put(Cfunctions.type_operation, Cfunctions.type_operation_commit_preference);
			jsonReq.put(Cfunctions.where_preference, preference.where.toUpperCase());
			jsonReq.put(Cfunctions.PK_MESSAGE, preference.PK_MESSAGE);
			jsonReq.put(Cfunctions.add_less_like_unlike, preference.add_less_like_unlike.toUpperCase());
			if (preference.where.equalsIgnoreCase("C")){
				foundIt=true;
				jsonReq.put(Cfunctions.PK_COMMENT, preference.PK_COMMENT);
			}else if (preference.where.equalsIgnoreCase("M")){
				foundIt=true;
			}
		}
		
		if (foundIt){
			ntwAgent=new FntwAgent(jsonReq.toString(), handlerTo);
			ntwAgent.start();
		}
	}
	
	public EpillFromServer decodeResponseJSON(String json){
		EpillFromServer fromServer=new EpillFromServer();
		try{
			JSONObject jsonDecode= new JSONObject(json);
			if (jsonDecode.getString(outcome_response).equalsIgnoreCase("Y")){
				fromServer.outcome_response='Y';
			}else if (jsonDecode.getString(outcome_response).equalsIgnoreCase("X")){
				fromServer.outcome_response='X';
			}else if (jsonDecode.getString(outcome_response).equalsIgnoreCase("W")){
				fromServer.outcome_response='W';
			}else{
				fromServer.outcome_response='X';
				fromServer.error=Cparams.INTERNAL_JSON_203 +" 'outcome_response'='"+jsonDecode.getString(outcome_response);
				return fromServer;
			}
			
			if (fromServer.outcome_response!='Y'){
				fromServer.error=jsonDecode.getString(error);
				fromServer.type_operation=jsonDecode.getString(type_operation);
				if (fromServer.type_operation.toUpperCase().contains("COMMIT")){
					fromServer.id_track_commit=jsonDecode.getString(id_track_commit);
				}
				return fromServer;
			}
			
			fromServer.type_operation=jsonDecode.getString(type_operation);
			
			if (fromServer.type_operation.equalsIgnoreCase(type_operation_commit_comment)){
				fromServer.id_track_commit=jsonDecode.getString(id_track_commit);
				fromServer.comments=new Ecomment[1];
				fromServer.comments[0]=new Ecomment();
				fromServer.comments[0].PK_COMMENT=jsonDecode.getInt(PK_COMMENT);
				fromServer.comments[0].FK_MESSAGE=jsonDecode.getInt(FK_MESSAGE);
				fromServer.comments[0].TMS_CREATED=jsonDecode.getLong(TMS_CREATED);
				fromServer.comments[0].TMS_LAST_COMMENT_UPDATE=fromServer.comments[0].TMS_CREATED;
				fromServer.comments[0].QTY_LIKE=0;
				fromServer.comments[0].QTY_UNLIKE=0;
				fromServer.comments[0].i_liked_unliked_this="N";
			}
			else if (fromServer.type_operation.equalsIgnoreCase(type_operation_commit_message)){
				fromServer.id_track_commit=jsonDecode.getString(id_track_commit);
				fromServer.messages=new Emessage[1];
				fromServer.messages[0]=new Emessage();
				fromServer.messages[0].PK_MESSAGE=jsonDecode.getInt(PK_MESSAGE);
				fromServer.messages[0].TMS_CREATED=jsonDecode.getLong(TMS_CREATED);
				fromServer.messages[0].TMS_LAST_MESSAGE_UPDATE=fromServer.messages[0].TMS_CREATED;
				fromServer.messages[0].i_liked_unliked_this="N";
				fromServer.messages[0].QTY_LIKE=0;
				fromServer.messages[0].QTY_UNLIKE=0;
			}
			else if (fromServer.type_operation.equalsIgnoreCase(type_operation_code_registration)){
			}
			else if (fromServer.type_operation.equalsIgnoreCase(type_operation_commit_preference)){
				fromServer.id_track_commit=jsonDecode.getString(id_track_commit);
			}
			else if (fromServer.type_operation.equalsIgnoreCase(type_operation_login)){
				fromServer.PK_SESSION=jsonDecode.getInt(PK_SESSION);
				fromServer.STX_USERID_CASE_SENSITIVE=jsonDecode.getString(STX_USERID_CASE_SENSITIVE);
			}
			else if (fromServer.type_operation.equalsIgnoreCase(type_operation_refresh)){
				fromServer.LNG_LAST_MACRO_BOUND_REFRESH=jsonDecode.getLong(LNG_LAST_MACRO_BOUND_REFRESH);
				JSONArray messagesArray=jsonDecode.getJSONArray(messages);
				JSONArray commentsArray=jsonDecode.getJSONArray(comments);
				
				fromServer.messages=new Emessage[messagesArray.length()];
				fromServer.comments=new Ecomment[commentsArray.length()];
				
				for (int i=0; i < messagesArray.length(); i++){
					JSONObject jsonMessage=messagesArray.getJSONObject(i);
					fromServer.messages[i]=new Emessage();
					fromServer.messages[i].PK_MESSAGE=jsonMessage.getInt(PK_MESSAGE);
					fromServer.messages[i].LNG_LATITUDE_IDX=jsonMessage.getLong(LNG_LATITUDE_IDX);
					fromServer.messages[i].LNG_LONGITUDE_IDX=jsonMessage.getLong(LNG_LONGITUDE_IDX);
					fromServer.messages[i].TMS_CREATED=jsonMessage.getLong(TMS_CREATED);
					fromServer.messages[i].TMS_LAST_MESSAGE_UPDATE=jsonMessage.getLong(TMS_LAST_MESSAGE_UPDATE);
					fromServer.messages[i].i_liked_unliked_this=jsonMessage.getString(i_liked_unliked_this).toUpperCase();
					fromServer.messages[i].QTY_LIKE=jsonMessage.getInt(QTY_LIKE);
					fromServer.messages[i].QTY_UNLIKE=jsonMessage.getInt(QTY_UNLIKE);
					fromServer.messages[i].ms_up_to_expiration=jsonMessage.getLong(ms_up_to_expiration);
					fromServer.messages[i].STX_USERID_CASE_SENSITIVE=jsonMessage.getString(STX_USERID_CASE_SENSITIVE);
					fromServer.messages[i].LTX_MESSAGE=jsonMessage.getString(LTX_MESSAGE);
				}
				
				for (int i=0; i < commentsArray.length(); i++){
					JSONObject jsonComment=commentsArray.getJSONObject(i);
					fromServer.comments[i]=new Ecomment();
					fromServer.comments[i].PK_COMMENT=jsonComment.getInt(PK_COMMENT);
					fromServer.comments[i].FK_MESSAGE=jsonComment.getInt(FK_MESSAGE);
					fromServer.comments[i].TMS_CREATED=jsonComment.getLong(TMS_CREATED);
					fromServer.comments[i].TMS_LAST_COMMENT_UPDATE=jsonComment.getLong(TMS_LAST_COMMENT_UPDATE);
					fromServer.comments[i].QTY_LIKE=jsonComment.getInt(QTY_LIKE);
					fromServer.comments[i].QTY_UNLIKE=jsonComment.getInt(QTY_UNLIKE);
					fromServer.comments[i].i_liked_unliked_this=jsonComment.getString(i_liked_unliked_this).toUpperCase();
					fromServer.comments[i].STX_USERID_CASE_SENSITIVE=jsonComment.getString(STX_USERID_CASE_SENSITIVE);
					fromServer.comments[i].LTX_COMMENT=jsonComment.getString(LTX_COMMENT);
				}
				
			}
			else if (fromServer.type_operation.equalsIgnoreCase(type_operation_registration)){
			}
			else if (fromServer.type_operation.equalsIgnoreCase(type_operation_logout)){
			}
			else if (fromServer.type_operation.equalsIgnoreCase(type_operation_ping)){
			}

		}catch(Exception en){
			if (en instanceof JSONException){
				fromServer.outcome_response='X';
				fromServer.error=Cparams.INTERNAL_JSON_201+en.getMessage();
			}else{
				fromServer.outcome_response='X';
				fromServer.error=Cparams.INTERNAL_EXCEPTION_202 + en.getMessage();
			}
		}
		return fromServer;
	}
	
	public static int calculateZoomLevel(int screenWidth, int meter) {
		//1km ruler (bottom left of the map) which is 90 pixels in length, at zoom level 13
	    int zoomLevel=10;
	    double metersPerPixel = Cparams.METER_90PX_10LEVEL*screenWidth/90;
	    while (metersPerPixel > meter) {
	    	metersPerPixel /= 2;
	        ++zoomLevel;
	    }
	    zoomLevel--;
	    return zoomLevel;
	}
	
	public static Logger getLogger(Object obj){
		LogConfigurator logConfigurator = new LogConfigurator();
        logConfigurator.setFileName(Cparams.PATH_N_FILE_LOG);
        logConfigurator.setRootLevel(Cparams.LEVEL);
        logConfigurator.setLevel("org.apache", Level.ERROR);
        logConfigurator.setFilePattern("%d %-5p [%c{2}]-[%L] %m%n");
        logConfigurator.setMaxFileSize(1024 * 1024 * 5);
        logConfigurator.setImmediateFlush(true);
        logConfigurator.configure();
        return Logger.getLogger(obj.getClass());
	}
	
	public static boolean deleteFileLog(){
		File file=new File(Cparams.PATH_N_FILE_LOG);
		return file.delete();
	}
	
	public static boolean createAndWriteFileLog(String text){
		BufferedWriter writer =null;
		String nameFileTemp=Cparams.PATH_N_FILE_LOG+"_TMP";
		try{
			File fileTmp=new File(nameFileTemp);
			fileTmp.delete();
			writer = new BufferedWriter(new FileWriter(fileTmp));
		    writer.write (text);
		    File file=new File(Cparams.PATH_N_FILE_LOG);
			file.delete();
			fileTmp.renameTo(file);
		}
		catch(IOException e){
			return false;
		}
		finally{
			try {
				writer.close();
			} catch (Exception e) {}
		}	
		return true;
	}
	
	public static String formatLog(String data){
		String dataLight=data.trim();
		if (dataLight.charAt(dataLight.length()-1)!=';')
			dataLight +=";";
		
		dataLight +=" "+System.getProperty("line.separator");
		
		return simpleDateTimeFormat.format(new Date(System.currentTimeMillis()))+"; "+dataLight;
		
	}

	protected static boolean isBetterLocation(Location location, Location currentBestLocation) {
		if (currentBestLocation == null) {
	        return true;
	    }
		
		float accuracyBestLocation=currentBestLocation.getAccuracy();
		float accuracyLocation=location.getAccuracy();
		
		if (accuracyLocation < accuracyBestLocation){ //nuova circonferenza migliore della vecchia
			return true;
		}
		
		float meter=location.distanceTo(currentBestLocation);
		
		if (meter > accuracyBestLocation && accuracyLocation < meter + accuracyBestLocation ){
			//baricentro nuova coordinata fuori dalla vecchia circonferenza && nuova circonferenza NON contiene  totalmente la vecchia circonferenza 
			return true;
		}
		return false;
		
	}

}
